package com.arpa.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.cache.ShipmentCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.wms.domain.dto.InventoryStatusDTO;
import com.arpa.wms.domain.entity.InventoryStatus;
import com.arpa.wms.domain.enums.DeleteFlagEnum;
import com.arpa.wms.domain.enums.StatusEnum;
import com.arpa.wms.domain.vo.InventoryStatusVO;
import com.arpa.wms.mapper.InventoryStatusMapper;
import com.arpa.wms.service.IInventoryService;
import com.arpa.wms.service.IInventoryStatusService;
import com.arpa.wms.service.IReceiveRegisterService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 库存状态 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-08-03
 */
@Service
public class InventoryStatusServiceImpl extends ServiceImpl<InventoryStatusMapper, InventoryStatus> implements IInventoryStatusService {


    private final ShipmentCache shipmentCache;
    private final PartyCache partyCache;

    private final IReceiveRegisterService iReceiveRegisterService;

    private final IInventoryService iInventoryService;

    public InventoryStatusServiceImpl(PartyCache partyCache, IReceiveRegisterService iReceiveRegisterService,
                                      IInventoryService iInventoryService, ShipmentCache shipmentCache) {
        this.partyCache = partyCache;
        this.iReceiveRegisterService = iReceiveRegisterService;
        this.iInventoryService = iInventoryService;
        this.shipmentCache = shipmentCache;
    }
    private  static  final  String INVENTORY_NAME_MANAGE = "名称不能重复";
    /**
     * 保存
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public boolean save(InventoryStatus entity) {
        //校验名称是否重复；

        InventoryStatus inventoryStatus = baseMapper.selectOne(new QueryWrapper<InventoryStatus>().lambda()
                .eq(InventoryStatus::getShipmentCode, entity.getShipmentCode())
                .eq(InventoryStatus::getName,entity.getName())
                .eq(InventoryStatus::getGroupCode,UserUtil.getBranchCode()));
        if(inventoryStatus != null){
            throw new ServiceException("库存状态名称已存在！");
        }
        entity.setCode(IdUtil.simpleUUID());
        entity.setDeleted(0);
        entity.setGroupCode(UserUtil.getBranchCode());
        entity.setStatus(StatusEnum.UNACTIVE.getValue());
        entity.setCreatedBy(UserUtil.getCode());
        entity.setCreatedName(partyCache.translate(UserUtil.getCode()));
        entity.setModifiedBy(UserUtil.getCode());
        entity.setModifiedName(partyCache.translate(UserUtil.getCode()));
        entity.setShipmentName(shipmentCache.translate(entity.getShipmentCode()));
        return super.save(entity);
    }
    /**
     * 根据code更新实体
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public int updateByCode(InventoryStatus entity) {
        entity.setModifiedBy(UserUtil.getCode());
        entity.setModifiedName(partyCache.translate(UserUtil.getCode()));

        InventoryStatus dbEntity = this.getOne(new QueryWrapper<InventoryStatus>().lambda().eq(InventoryStatus::getCode, entity.getCode())
        .eq(InventoryStatus::getGroupCode,UserUtil.getBranchCode()));
        if (dbEntity == null) {
            throw new ServiceException("数据主键信息不存在");
        }


        int updateCount = baseMapper.update(entity,new QueryWrapper<InventoryStatus>().lambda().eq(InventoryStatus::getCode,entity.getCode()).eq(InventoryStatus::getGroupCode,UserUtil.getBranchCode()));


        return updateCount;
    }

    /**
     * 查询列表
     * @param inventoryStatusDTO
     * @return
     */
    @Override
    public List<InventoryStatusVO> queryList(InventoryStatusDTO inventoryStatusDTO){
        //排序字段名需要驼峰转数据库下划线类型字段名
        if(StringUtils.isNotEmpty(inventoryStatusDTO.getSortField())){
            inventoryStatusDTO.setSortField(CommonUtil.camel2Underline(inventoryStatusDTO.getSortField()));


            if (!"status_text".equals(inventoryStatusDTO.getSortField())) {
            } else {
                inventoryStatusDTO.setSortField("a.status");
            }
        }
        List<InventoryStatusVO> inventoryStatusVOList = baseMapper.queryList(inventoryStatusDTO);
        inventoryStatusVOList.forEach(info ->{
            info.setShipmentName(shipmentCache.translate(info.getShipmentCode()));
            /*info.setCreatedByName(partyCache.translate(info.getCreatedBy()));
            info.setModifiedByName(partyCache.translate(info.getModifiedBy()));*/
            StatusEnum enumByValue = StatusEnum.getEnumByValue(info.getUsings());
            if (null != enumByValue) {
                info.setUsingsName(enumByValue.getDesc());
            }
        });
        return inventoryStatusVOList;
    }

    @Override
    public List<InventoryStatusVO> queryByCodes(List<String> codes) {

        return baseMapper.getByCodes(codes,UserUtil.getBranchCode());
    }

    /**
     * 通过code获取库存状态
     *
     * @param code
     * @return
     */
    @Override
    public InventoryStatusVO getOneByCode(String code) {
        InventoryStatus inventoryStatus = baseMapper.selectOne(new QueryWrapper<InventoryStatus>().lambda().eq(InventoryStatus::getCode,code).eq(InventoryStatus::getGroupCode,UserUtil.getBranchCode()));
        if(inventoryStatus!=null){
            InventoryStatusVO vo = new InventoryStatusVO();
            BeanUtil.copyProperties(inventoryStatus,vo,false);
            vo.setShipmentName(shipmentCache.translate(vo.getShipmentCode()));
            StatusEnum enumByValue = StatusEnum.getEnumByValue(vo.getUsings());
            if (null != enumByValue) {
                vo.setUsingsName(enumByValue.getDesc());
            }
            return vo;
        }
        return null;
    }

    /**
     * 查询合计,包含总数
     * @param inventoryStatusDTO
     * @return
     */
    @Override
    public InventoryStatusVO queryListSum(InventoryStatusDTO inventoryStatusDTO){
        InventoryStatusVO inventoryStatusVO = baseMapper.queryListSum(inventoryStatusDTO);
        return inventoryStatusVO;
    }
    /**
     * 批量删除
     * @param codes
     */
    @Transactional(rollbackFor = {Exception.class})
    @Override
    public  Map<String,Object> batchdel(List<String> codes) {

        Map<String,Object> result;
        result = new HashMap<>();
        List<InventoryStatusVO> statusVOS = queryByCodes(codes);
        Map<String, String> statusMap = statusVOS.stream().collect(Collectors.toMap(InventoryStatusVO::getCode, InventoryStatusVO::getName));
        //不可删除code
        List<String> notDeleteCodes = statusVOS.stream().filter(info -> info.getDeleteFlag().intValue() == DeleteFlagEnum.NOTDELETE.getCode().intValue()).map(info -> {
            return info.getCode();
        }).collect(Collectors.toList());
        int num = 0;
        if(IterUtil.isNotEmpty(notDeleteCodes)){
            List<String> notDelete = notDeleteCodes.stream().map(code -> {
                return statusMap.get(code);
            }).collect(Collectors.toList());
            result.put("notDelete",notDelete);
            //可删除code
            List<String> deleteCodes = codes.stream().filter(r -> !notDeleteCodes.contains(r)).collect(Collectors.toList());
            num = delete(deleteCodes);
        }else {
            num = delete(codes);
        }
        result.put("success",num);
        return result;
    }

    private int delete(List<String> list){
        int num = 0;
        if(IterUtil.isNotEmpty(list)){
            for(String code : list){
                this.update(new UpdateWrapper<InventoryStatus>().lambda().eq(InventoryStatus::getCode, code)
                        .set(InventoryStatus::getDeleted, 1).eq(InventoryStatus::getGroupCode,UserUtil.getBranchCode()));
                num++;
            }
        }
        return num;
    }

    /**
     *  根据code更新启用、停用状态
     * @param codes
     * @param active
     * @return
     */
    @Override
    public Map<String,Object> activeStatus(List<String> codes, StatusEnum active) {
            HashMap<String, Object> result;
        result = new HashMap<>();
        int num = 0;
            if (active.getValue().equals(StatusEnum.UNACTIVE.getValue())) {
                val receiveRes = iReceiveRegisterService.queryByInventoryStatus(codes);
                List<String> statusList = receiveRes.stream().map(info -> {
                    return info.getGoodsStatus();
                }).collect(Collectors.toList());
                //收货登记使用的数据
                List<String> receiveUsedList = statusList.stream().distinct().collect(Collectors.toList());
                val inventoryRes = iInventoryService.queryByInventoryStatus(codes);
                List<String> list = inventoryRes.stream().map(info -> {
                    return info.getGoodsStatus();
                }).collect(Collectors.toList());
                //库存使用的数据
                List<String> inventoryUsedList = list.stream().distinct().collect(Collectors.toList());
                List<String> temp = new ArrayList<>();
                temp.addAll(receiveUsedList);
                temp.addAll(inventoryUsedList);
                List<String> query = temp.stream().distinct().collect(Collectors.toList());
                if (IterUtil.isNotEmpty(query)) {
                    List<InventoryStatusVO> inventoryStatusVOS = this.baseMapper.getByCodes(query,UserUtil.getBranchCode());
                    Map<String, String> inventoryStatusMap = inventoryStatusVOS.stream().collect(Collectors.toMap(InventoryStatusVO::getCode, InventoryStatusVO::getName));
                    List<String> receiveUseName = receiveUsedList.stream().map(code -> {
                        return inventoryStatusMap.get(code);
                    }).collect(Collectors.toList());
                    result.put("receiveUseName", receiveUseName);
                    List<String> inventoryUseName = inventoryUsedList.stream().map(code -> {
                        return inventoryStatusMap.get(code);
                    }).collect(Collectors.toList());
                    result.put("inventoryUseName", inventoryUseName);
                }
                List<String> update = codes.stream().filter(code -> !query.contains(code)).collect(Collectors.toList());
                if (IterUtil.isNotEmpty(update)) {
                    String codesStr = update.stream().map(c -> StrUtil.wrap(c, "'")).collect(Collectors.joining(","));
                    num = this.baseMapper.changeStatus(codesStr, active.getValue(), DeleteFlagEnum.NOTDELETE.getCode().toString(),UserUtil.getBranchCode());
                }
            } else {
                String codesStr = codes.stream().map(c -> StrUtil.wrap(c, "'")).collect(Collectors.joining(","));
                num = this.baseMapper.changeStatus(codesStr, active.getValue(), DeleteFlagEnum.NOTDELETE.getCode().toString(),UserUtil.getBranchCode());
            }
            result.put("success", num);
            return result;
        }
    }

